package com.nervenets.web.controller.buildPromotion;

import com.nervenets.utils.StringUtils;
import com.nervenets.web.controller.BaseController;
import com.nervenets.web.controller.CheckParams;
import com.nervenets.web.controller.IdParams;
import com.nervenets.web.controller.IdTokenParams;
import com.nervenets.web.controller.promotion.PromotionEditParams;
import com.nervenets.web.controller.promotion.PromotionPagingParams;
import com.nervenets.web.entity.KeyValue;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.enumeration.CheckStatus;
import com.nervenets.web.hibernate.dao.BuildPromotionDao;
import com.nervenets.web.hibernate.dao.BuildingDao;
import com.nervenets.web.hibernate.dao.ManagerDao;
import com.nervenets.web.hibernate.dao.PromotionDao;
import com.nervenets.web.hibernate.domain.BuildPromotion;
import com.nervenets.web.hibernate.domain.Building;
import com.nervenets.web.hibernate.domain.Manager;
import com.nervenets.web.hibernate.domain.Promotion;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Api(value = "楼盘活动接口v1", description = "楼盘活动类接口")
@RestController
@RequestMapping("/api/v1/buildPromotion")
public class BuildPromotionController extends BaseController {
    @Resource
    private BuildPromotionDao buildPromotionDao;
    @Resource
    private BuildingDao buildingDao;
    @Resource
    private ManagerDao managerDao;

    @ApiOperation("楼盘活动列表")
    @PostMapping("/list")
    public String list(@RequestBody BuildPromotionPagingParams params) {
        final Set<ConstraintViolation<BuildPromotionPagingParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        Specification<BuildPromotion> specification = (Specification<BuildPromotion>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isEmpty(params.getTitle())) {
                predicates.add(criteriaBuilder.like(root.get("title"), "%" + params.getTitle() + "%"));
            }
            switch (params.getEnable()) {
                case 0:
                    break;
                case 1:
                    predicates.add(criteriaBuilder.isTrue(root.get("enable")));
                    break;
                case 2:
                    predicates.add(criteriaBuilder.isFalse(root.get("enable")));
                    break;
            }
            if (params.getManagerId() > 0) {
                predicates.add(criteriaBuilder.equal(root.get("managerId"), params.getManagerId()));
            }
            if (params.getBuildingId() > 0) {
                predicates.add(criteriaBuilder.equal(root.get("buildingId"), params.getBuildingId()));
            }
            if (null != params.getCheckStatus()) {
                predicates.add(criteriaBuilder.equal(root.get("checkStatus"), params.getCheckStatus()));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        final Page<BuildPromotion> pages = buildPromotionDao.findAll(specification, PageRequest.of(params.getPage(), params.getLimit(), new Sort(Sort.Direction.DESC, "queue")));
        List<BuildPromotionDto> dtos = new ArrayList<>();
        pages.map(buildPromotion -> dtos.add(new BuildPromotionDto(buildPromotion, globalService)));
        return successMessage(dtos, new KeyValue("page", params.getPage()), new KeyValue("total", pages.getTotalElements()));
    }

    @ApiOperation("楼盘活动详情")
    @PostMapping("/detail")
    public String detail(@RequestBody IdParams params) {
        final Set<ConstraintViolation<IdParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        BuildPromotion promotion = buildPromotionDao.findById(params.getTargetId()).orElse(null);
        if (null == promotion) return errorMessage(MessageCode.code_404, "您要查看的楼盘活动不存在");

        return successMessage(promotion);
    }

    @ApiOperation("楼盘审核")
    @PostMapping("/check")
    public String check(@RequestBody CheckParams params) throws Exception {
        final Set<ConstraintViolation<CheckParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }
        return (String) redisSyncLocker.idLock(params.getTargetId(), o -> {
            BuildPromotion building = buildPromotionDao.findById(params.getTargetId()).orElse(null);
            if (null == building) return errorMessage(MessageCode.code_404);
            building.setCheckStatus(params.getChangeTo());
            building.setRemark(params.getReason());
            buildPromotionDao.save(building);
            return successMessage(building);
        });
    }

    @ApiOperation("楼盘活动添加或编辑")
    @PostMapping("/edit")
    public String edit(@RequestBody BuildPromotionEditParams params) {
        final Set<ConstraintViolation<BuildPromotionEditParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        final Manager manager = managerDao.findById(params.resolveUserId()).orElse(null);
        if (null == manager) return errorMessage(MessageCode.code_777);

        final Building building = buildingDao.findTop1ByManager(manager);
        if (null == building) return errorMessage(MessageCode.code_404, "您选择的开发商未完善楼盘信息");

        BuildPromotion promotion = new BuildPromotion();
        if (params.getPromotionId() > 0) {
            promotion = buildPromotionDao.findById(params.getPromotionId()).orElse(null);
            if (null == promotion) return errorMessage(MessageCode.code_404, "您编辑的楼盘活动不存在");
        }

        promotion.setManagerId(building.getManager().getId());
        promotion.setBuildingId(building.getId());
        promotion.setTitle(params.getTitle());
        promotion.setCover(params.getCover());
        promotion.setContent(params.getContent());
        promotion.setQueue(params.getQueue());
        promotion.setEnable(params.isEnable());
        promotion.setCheckStatus(CheckStatus.checking);
        buildPromotionDao.save(promotion);

        return successMessage();
    }

    @ApiOperation("楼盘活动删除")
    @PostMapping("/del")
    public String del(@RequestBody IdTokenParams params) {
        final Set<ConstraintViolation<IdTokenParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        BuildPromotion promotion = buildPromotionDao.findById(params.getTargetId()).orElse(null);
        if (null == promotion) return errorMessage(MessageCode.code_404, "您要删除的楼盘活动不存在");

        buildPromotionDao.delete(promotion);

        return successMessage();
    }
}
